using Gtk;
using Gee;

namespace Atlantis
{
    public class ProjectExplorer : GLib.Object, IWidgetProvider, ISmartPartInfoProvider, IEventHandler, IInjectRegistry
    {
	    private TreeStore store; 
	    private Widget widget;
        private TreeView treeView;
	    private ProjectNode project;
	    private Registry registry;
	    
	    public Registry Registry {
			get {
				return this.registry;
			}
			set {
				this.registry = value;
			}
		}
	    
	    construct {
			Initialize();
		}
		
		private void Initialize(){
			stderr.printf("Initialize");
			var builder = new Builder();
            builder.add_from_file ("ui.glade");
            widget = builder.get_object("ProjectExplorerView") as Widget;
            treeView = builder.get_object("ProjectTreeView") as TreeView;
            builder.connect_signals (this);
		}
	    
	    public ISmartPartInfo GetSmartPartInfo() {
            stderr.printf("GetSmartPartInfo()\n");
            var ret = new SmartPartInfo();
            ret.Label = "Project Explorer";
            return ret;
        }

        public Widget Widget {
            get {
                return this.widget;
            }
        }
        
        public bool handles_event<T>() {
			stderr.printf("\nevent handled");
			return typeof(OpenProjectEvent) == typeof(T);
		}
		
		public void handle_event<T>(T event) {
			stderr.printf("\nevent handled");
			OpenProjectEvent openProjectEvent = (OpenProjectEvent)event;
			Load(openProjectEvent.Project);	
		}

	    public void Load(ProjectNode project) {	
            this.store = new TreeStore(2, typeof(string), typeof(string));
		    this.treeView.set_model (store);
		    this.treeView.insert_column_with_attributes (-1, "Name", new CellRendererText(), "text", 0, null);
            LoadIntoTree(store, null, project);
            this.project = project;
    	}

		[CCode(instance_pos=-1)]
		public void on_ProjectTreeView_row_activated(TreeView sender, TreePath path, TreeViewColumn col) {
			
			Gtk.TreeIter iter;
			Gtk.TreeModel model;

			file_select(sender, path, col);
		}
		
		private void file_select (Gtk.TreeView sender, Gtk.TreePath path, Gtk.TreeViewColumn column) {
			Gtk.TreeIter iter;
			string selectedNodeId;

			this.store.get_iter (out iter, path);
			this.store.get (iter, 1, out selectedNodeId);
			Node selectedNode = project.find_by_id( selectedNodeId );
			
			if (selectedNode is DocumentNode)
			{
				string filename = ((DocumentNode)selectedNode).RelativePath;
				Document document = new Document(filename);
				DocumentPresenter presenter = new DocumentPresenter(Registry);
				IDocumentView idocumentView = Registry.Get<IDocumentView>();
				presenter.View = idocumentView;
				idocumentView.Load(document);
				Registry.Workspaces["DOCUMENT_WORKSPACE"].Add(idocumentView);
			}
			
			if (selectedNode is CompositeNode) {
				if (this.treeView.is_row_expanded (path)) {
					this.treeView.collapse_row (path);
				}
				else {
					this.treeView.expand_row (path, false);
				}		
			}
		}

		
	    void LoadIntoTree(TreeStore treeStore, TreeIter? parentIter, Node node) {
            TreeIter iter;
            treeStore.append(out iter, parentIter);
	    	treeStore.set(iter, 0, node.Text, 1, node.Id, -1);

	        if (node is CompositeNode) {
                foreach (Node child in ((CompositeNode)node).Children) {
			        LoadIntoTree(treeStore, iter, child);
                }
			}
	    }
    }
}
